package com.mayuanfei.controller;

import cn.hutool.core.io.IoUtil;
import com.mayuanfei.config.S3Properties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.ResponseInputStream;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.time.Duration;

/**
 * TODO 类描述
 *
 * @author 老马
 * @date 2024-12-23 14:49
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/minio")
public class S3Controller {

    private final S3Client s3Client;
    private final S3Presigner s3Presigner;
    private final S3Properties s3Properties;

    /**
     * 上传文件
     */
    @RequestMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) {
            // 创建上传请求
            PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                    .bucket(s3Properties.getBucketName())
                    .key("test/" + file.getOriginalFilename())
                    .contentType(file.getContentType())
                    .build();
            // 上传文件到 Minio
            s3Client.putObject(putObjectRequest, RequestBody.fromInputStream(inputStream, file.getSize()));
            return "上传成功";
        } catch (Exception e) {
            log.error("上传文件失败", e);
            return "上传失败";
        }
    }

    @RequestMapping("/download")
    public void download(@RequestParam("fileName") String fileName, HttpServletResponse response) {
        try {
            // 创建 GetObjectRequest 用于获取对象
            GetObjectRequest getObjectRequest = GetObjectRequest.builder()
                    .bucket(s3Properties.getBucketName())
                    .key(fileName)
                    .build();
            ResponseInputStream<GetObjectResponse> object = s3Client.getObject(getObjectRequest);

            // 设置响应头
            response.setContentType(object.response().contentType());
            response.setHeader("Content-Disposition",
                    "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
            // 写入响应流
            IoUtil.copy(object, response.getOutputStream());
            response.getOutputStream().flush();
        } catch (Exception e) {
            log.error("下载文件失败", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 获取文件访问的完整URL (AS3接口方式)
     */
    @RequestMapping("/fileUrl")
    public String getFileUrl(@RequestParam("fileName") String fileName) {
        try {
//            // 直接用 s3Client 构造 URL 。适用于public bucket
//            URL url = s3Client.utilities().getUrl(builder -> builder.bucket(s3Properties.getBucketName()).key(fileName));
//            return url.toString();

            // 生成预签名 URL
            PresignedGetObjectRequest presignedRequest = s3Presigner.presignGetObject(builder ->
                    builder.getObjectRequest(getBuilder ->
                                    getBuilder.bucket(s3Properties.getBucketName()).key(fileName))
                            // 签名有效期为1个小时
                            .signatureDuration(Duration.ofHours(1))
            );

            return presignedRequest.url().toString();
        } catch (Exception e) {
            return "获取文件URL失败：" + e.getMessage();
        }
    }


    /**
     * 删除文件
     */
    @RequestMapping("/delete")
    public String deleteFile(@RequestParam("fileName") String fileName) {
        try {
            // 调用 S3Client 的 deleteObject 方法删除文件
            s3Client.deleteObject(builder ->
                    builder.bucket(s3Properties.getBucketName()).key(fileName)
            );
            log.info("文件 {} 删除成功", fileName);
            return "删除成功";
        } catch (Exception e) {
            log.error("删除文件失败", e);
            return "删除失败：" + e.getMessage();
        }
    }

}